// Copyright 2022 jeff.li. and/or its affiliates.

#pragma once

#include <stdlib.h>

#include <mutex>

namespace tbir::runtime {

    template<class T>
    class Singleton {
    public:
        friend T;

        static T *instance() {
            if (_s_instance == NULL) {
                std::lock_guard<std::mutex> lock(s_singleton_mutex_);
                if (_s_instance == NULL) {
                    _s_instance = new T;
                }
            }
            return _s_instance;
        }

    private:
        static T *_s_instance;
        static std::mutex s_singleton_mutex_;
    };

    template<class T>
    T *Singleton<T>::_s_instance = NULL;

    template<class T>
    std::mutex Singleton<T>::s_singleton_mutex_;

}  // namespace tbir::runtime
